﻿using Domain.Entity.OperationLogD;
using Infrastructure.IRepository.Base;
using System.Diagnostics;
using System.Text;

namespace ApiServer.Middelware
{
    public static class RequestLogMiddlewareExt
    {
        public static IApplicationBuilder UseRequestLogMiddleware(this
        IApplicationBuilder builder)
        {
            return builder.UseMiddleware<LogMSGMiddleware>();
        }

    }
    /// <summary>
    /// 自定义日志中间件
    /// </summary>
    public class LogMSGMiddleware
    {
        private readonly RequestDelegate _nxt;
        private readonly IServiceProvider _serviceProvider;
        //private readonly IOperationLogService _operationService;
        private readonly ILogger<LogMSGMiddleware> _logger;
        private const string LOGIN_PATH = @"/api/user/login"; //登录api的请求路径
        //http://localhost:5102/user/login
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="nxt"></param>
        /// <param name="serviceProvider"></param>
        /// <param name="logger"></param>
        public LogMSGMiddleware(RequestDelegate nxt,
                                ILogger<LogMSGMiddleware> logger,
                                IServiceProvider serviceProvider)
        {
            _nxt = nxt;
            _logger = logger;
            _serviceProvider = serviceProvider;
        }

        /// <summary>
        /// 调用处理
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context)
        {
            var headers = context.Request.Headers; //请求头
            var body = context.Request.Body;       //请求体
            var method = context.Request.Method;   //请求方式
            var path = context.Request.Path;       //请求路径
            var accesToken = context.Request.Headers["Authorization"];
            HttpRequest request = context.Request;
            //Stream straem = request.Body;
            //Encoding encoding = Encoding.UTF8;
            string data = string.Empty;
            request.EnableBuffering();//启用缓存
            using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true))
            {
                //data就是post传过来的值json格式
                data = await reader.ReadLineAsync();
                request.Body.Position = 0;
            }
            //获取用户名
            string username = context.User.FindFirst("UName")?.Value;
            if (string.IsNullOrEmpty(username))
            {
                username = "游客";
            }

            try
            {
                #region   计时器,记录运行时长
                Stopwatch stopwatch = new Stopwatch();

                stopwatch.Start();

                await _nxt(context);

                stopwatch.Stop();
                string milliseconds = stopwatch.ElapsedMilliseconds.ToString() + "毫秒";//运行耗时
                #endregion

                //获取操作日志的应用服务对象
                IOperationLogService operationService = _serviceProvider.GetRequiredService<IOperationLogService>();

                //判断用户的请求是不是登录
                if (path.ToString().ToLower() == LOGIN_PATH)
                {
                    OperationLog operation = new OperationLog
                    {
                        CreateTimes = DateTime.Now, //创建时间
                        Use = "OAWeb.ApiHost",      //应用
                        Classify = "登录日志",       //分类
                        Whether = true,             //是否异常
                        Content = "用户登录，操作耗时：" + milliseconds,   //内容
                        Module = path,              //模块
                        OperatorName = username     //用户名
                    };
                    operationService.Add(operation);
                }
                else
                {
                    OperationLog operation = new OperationLog
                    {
                        CreateTimes = DateTime.Now, //创建时间
                        Use = "OAWeb.ApiHost",      //应用
                        Classify = "访问日志",       //分类
                        Whether = true,             //是否异常
                        Content = "用户访问，操作耗时：" + milliseconds,   //内容
                        Module = path,              //模块
                        OperatorName = username     //用户名
                    };
                    operationService.Add(operation);
                }
            }
            catch (Exception ex)
            {
                //异常日志记录到文件
                _logger.LogError($"请求异常:{path}，错误信息：{ex.Message}");

            }

        }

    }
}
